home *** CD-ROM | disk | FTP | other *** search
- /*
- (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
- Copying of this file is authorized to users who have executed the true and
- proper "License Agreement for Kyoto Common LISP" with SIGLISP.
- */
-
- /*
- num_co.c
- IMPLEMENTATION-DEPENDENT
-
- This file contains those functions
- that know the representation of floating-point numbers.
- */
-
- #include "include.h"
- #include "num_include.h"
-
- object plus_half, minus_half;
-
-
- #ifdef VAX
- /*
- radix = 2
-
- SEEEEEEEEHHHHHHH The redundant most significant fraction bit
- HHHHHHHHHHHHHHHH is not expressed.
- LLLLLLLLLLLLLLLL
- LLLLLLLLLLLLLLLL
- */
- #endif
- #ifdef IBMRT
-
-
-
-
-
-
-
-
- #endif
- #ifdef IEEEFLOAT
- #ifdef NS32K
-
-
-
-
-
-
-
- #else
- /*
- radix = 2
-
- SEEEEEEEEEEEHHHHHHHHHHHHHHHHHHHH The redundant most
- LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL significant fraction bit
- is not expressed.
- */
- #endif
- #endif
- #ifdef MV
-
-
-
-
-
-
- #endif
- #ifdef S3000
- /*
- radix = 16
-
- SEEEEEEEHHHHHHHHHHHHHHHHHHHHHHHH
- LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
- */
- #endif
- integer_decode_double(d, hp, lp, ep, sp)
- double d;
- int *hp, *lp, *ep, *sp;
- {
- int h, l;
-
- if (d == 0.0) {
- *hp = *lp = 0;
- *ep = 0;
- *sp = 1;
- return;
- }
- #ifdef NS32K
-
-
- #else
- h = *(int *)(&d);
- l = *((int *)(&d) + 1);
- #endif
- #ifdef VAX
- *ep = ((h >> 7) & 0xff) - 128 - 56;
- h = ((h >> 15) & 0x1fffe) | (((h & 0x7f) | 0x80) << 17);
- l = ((l >> 16) & 0xffff) | (l << 16);
- #endif
- #ifdef IBMRT
-
-
-
- #endif
- #ifdef IEEEFLOAT
- *ep = ((h & 0x7ff00000) >> 20) - 1022 - 53;
- h = (h & 0x000fffff | 0x00100000) << 1;
- #endif
- #ifdef MV
-
-
- #endif
- #ifdef S3000
- *ep = ((h & 0x7f000000) >> 24) - 64 - 14;
- h = (h & 0x00ffffff) << 1;
- #endif
- if (l < 0) {
- h++;
- l &= 0x7fffffff;
- }
- *hp = h;
- *lp = l;
- *sp = (d > 0.0 ? 1 : -1);
- }
-
- #ifdef VAX
- /*
- radix = 2
-
- SEEEEEEEEMMMMMMM The redundant most significant fraction bit
- MMMMMMMMMMMMMMMM is not expressed.
- */
- #endif
- #ifdef IBMRT
-
-
-
-
-
-
- #endif
- #ifdef IEEEFLOAT
- /*
- radix = 2
-
- SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM The redundant most
- significant fraction bit
- is not expressed.
- */
- #endif
- #ifdef MV
-
-
-
-
-
- #endif
- #ifdef S3000
- /*
- radix = 16
-
- SEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMM
- */
- #endif
- integer_decode_float(d, mp, ep, sp)
- double d;
- int *mp, *ep, *sp;
- {
- float f;
- int m;
-
- f = d;
- if (f == 0.0) {
- *mp = 0;
- *ep = 0;
- *sp = 1;
- return;
- }
- m = *(int *)(&f);
- #ifdef VAX
- *ep = ((m >> 7) & 0xff) - 128 - 24;
- *mp = ((m >> 16) & 0xffff) | (((m & 0x7f) | 0x80) << 16);
- #endif
- #ifdef IBMRT
-
-
- #endif
- #ifdef IEEEFLOAT
- *ep = ((m & 0x7f800000) >> 23) - 126 - 24;
- *mp = m & 0x007fffff | 0x00800000;
- #endif
- #ifdef MV
-
-
- #endif
- #ifdef S3000
- *ep = ((m & 0x7f000000) >> 24) - 64 - 6;
- *mp = m & 0x00ffffff;
- #endif
- *sp = (f > 0.0 ? 1 : -1);
- }
-
- int
- double_exponent(d)
- double d;
- {
- if (d == 0.0)
- return(0);
- #ifdef VAX
- return(((*(int *)(&d) >> 7) & 0xff) - 128);
- #endif
- #ifdef IBMRT
-
- #endif
- #ifdef IEEEFLOAT
- #ifdef NS32K
-
- #else
- return(((*(int *)(&d) & 0x7ff00000) >> 20) - 1022);
- #endif
- #endif
- #ifdef MV
-
- #endif
- #ifdef S3000
- return(((*(int *)(&d) & 0x7f000000) >> 24) - 64);
- #endif
- }
-
- double
- set_exponent(d, e)
- double d;
- int e;
- {
- double dummy;
-
- if (d == 0.0)
- return(0.0);
- *(int *)(&d)
- #ifdef VAX
- = *(int *)(&d) & 0xffff807f | ((e + 128) << 7) & 0x7f80;
- #endif
- #ifdef IBMRT
-
- #endif
- #ifdef IEEEFLOAT
- #ifdef NS32K
-
- #else
- = *(int *)(&d) & 0x800fffff | ((e + 1022) << 20) & 0x7ff00000;
- #endif
- #endif
- #ifdef MV
-
- #endif
- #ifdef S3000
- = *(int *)(&d) & 0x80ffffff | ((e + 64) << 24) & 0x7f000000;
- #endif
- dummy = d*d;
- return(d);
- }
-
-
- object
- double_to_integer(d)
- double d;
- {
- int h, l, e, s;
- object x, y;
- object shift_integer();
- vs_mark;
-
- if (d == 0.0)
- return(small_fixnum(0));
- integer_decode_double(d, &h, &l, &e, &s);
- #ifdef VAX
- if (e <= -31) {
- h >>= (-e) - 31;
- #endif
- #ifdef IBMRT
-
-
- #endif
- #ifdef IEEEFLOAT
- if (e <= -31) {
- e = (-e) - 31;
- if (e >= 31)
- return(small_fixnum(0));
- h >>= e;
- #endif
- #ifdef MV
-
-
- #endif
- #ifdef S3000
- if (e <= -8) {
- h >>= 4*(-e) - 31;
- #endif
- return(make_fixnum(s*h));
- }
- if (h != 0)
- x = bignum2(h, l);
- else
- x = make_fixnum(l);
- vs_push(x);
- #ifdef VAX
- x = shift_integer(x, e);
- #endif
- #ifdef IBMRT
-
- #endif
- #ifdef IEEEFLOAT
- x = shift_integer(x, e);
- #endif
- #ifdef MV
-
- #endif
- #ifdef S3000
- x = shift_integer(x, 4*e);
- #endif
- if (s < 0) {
- vs_push(x);
- x = number_negate(x);
- }
- vs_reset;
- return(x);
- }
-
- object
- remainder(x, y, q)
- object x, y, q;
- {
- object z;
-
- z = number_times(q, y);
- vs_push(z);
- z = number_minus(x, z);
- vs_pop;
- return(z);
- }
-
-
- Lfloat()
- {
- double d;
- int narg;
- object x;
- enum type t;
-
- narg = vs_top - vs_base;
- if (narg < 1)
- too_few_arguments();
- else if (narg > 2)
- too_many_arguments();
- if (narg == 2) {
- check_type_float(&vs_base[1]);
- t = type_of(vs_base[1]);
- }
- x = vs_base[0];
- switch (type_of(x)) {
- case t_fixnum:
- if (narg > 1 && t == t_longfloat)
- x = make_longfloat((double)(fix(x)));
- else
- x = make_shortfloat((shortfloat)(fix(x)));
- break;
-
- case t_bignum:
- case t_ratio:
- d = number_to_double(x);
- if (narg > 1 && t == t_longfloat)
- x = make_longfloat(d);
- else
- x = make_shortfloat((shortfloat)d);
- break;
-
- case t_shortfloat:
- if (narg > 1 && t == t_longfloat)
- x = make_longfloat((double)(sf(x)));
- break;
-
- case t_longfloat:
- if (narg > 1 && t == t_shortfloat)
- x = make_shortfloat((shortfloat)(lf(x)));
- break;
-
- default:
- FEwrong_type_argument(TSor_rational_float, x);
- }
- vs_base = vs_top;
- vs_push(x);
- }
-
- Lnumerator()
- {
- check_arg(1);
- check_type_rational(&vs_base[0]);
- if (type_of(vs_base[0]) == t_ratio)
- vs_base[0] = vs_base[0]->rat.rat_num;
- }
-
- Ldenominator()
- {
- check_arg(1);
- check_type_rational(&vs_base[0]);
- if (type_of(vs_base[0]) == t_ratio)
- vs_base[0] = vs_base[0]->rat.rat_den;
- else
- vs_base[0] = small_fixnum(1);
- }
-
- Lfloor()
- {
- object x, y, q, q1;
- double d;
- int n;
- object one_minus();
-
- n = vs_top - vs_base;
- if (n == 0)
- too_few_arguments();
- if (n > 1)
- goto TWO_ARG;
- x = vs_base[0];
- switch (type_of(x)) {
-
- case t_fixnum:
- case t_bignum:
- vs_push(small_fixnum(0));
- return;
-
- case t_ratio:
- q = x;
- y = small_fixnum(1);
- goto RATIO;
-
- case t_shortfloat:
- d = (double)(sf(x));
- q1 = double_to_integer(d);
- d -= number_to_double(q1);
- if (sf(x) < 0.0 && d != 0.0) {
- vs_push(q1);
- q1 = one_minus(q1);
- d += 1.0;
- }
- vs_base = vs_top;
- vs_push(q1);
- vs_push(make_shortfloat((shortfloat)d));
- return;
-
- case t_longfloat:
- d = lf(x);
- q1 = double_to_integer(d);
- d -= number_to_double(q1);
- if (lf(x) < 0.0 && d != 0.0) {
- vs_push(q1);
- q1 = one_minus(q1);
- d += 1.0;
- }
- vs_base = vs_top;
- vs_push(q1);
- vs_push(make_longfloat(d));
- return;
-
- default:
- FEwrong_type_argument(TSor_rational_float, x);
- }
-
- TWO_ARG:
- if (n > 2)
- too_many_arguments();
- x = vs_base[0];
- y = vs_base[1];
- if ((type_of(x) == t_fixnum || type_of(x) == t_bignum) &&
- (type_of(y) == t_fixnum || type_of(y) == t_bignum)) {
- vs_base = vs_top;
- if (number_zerop(x)) {
- vs_push(small_fixnum(0));
- vs_push(small_fixnum(0));
- return;
- }
- vs_push(Cnil);
- vs_push(Cnil);
- integer_quotient_remainder_1(x, y, &vs_base[0], &vs_base[1]);
- if (number_minusp(x) ? number_plusp(y) : number_minusp(y)) {
- if (number_zerop(vs_base[1]))
- return;
- vs_base[0] = one_minus(vs_base[0]);
- vs_base[1] = number_plus(vs_base[1], y);
- }
- return;
- }
- check_type_or_rational_float(&vs_base[0]);
- check_type_or_rational_float(&vs_base[1]);
- q = number_divide(x, y);
- vs_push(q);
- switch (type_of(q)) {
- case t_fixnum:
- case t_bignum:
- vs_base = vs_top;
- vs_push(q);
- vs_push(small_fixnum(0));
- break;
-
- case t_ratio:
- RATIO:
- q1 = integer_divide1(q->rat.rat_num, q->rat.rat_den);
- if (number_minusp(q)) {
- vs_push(q1);
- q1 = one_minus(q1);
- } else
- q1 = q1;
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
-
- case t_shortfloat:
- case t_longfloat:
- q1 = double_to_integer(number_to_double(q));
- if (number_minusp(q1) && number_compare(q, q1)) {
- vs_push(q1);
- q1 = one_minus(q1);
- } else
- q1 = q1;
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
- }
- }
-
- Lceiling()
- {
- object x, y, q, q1;
- double d;
- int n;
- object one_plus();
-
- n = vs_top - vs_base;
- if (n == 0)
- too_few_arguments();
- if (n > 1)
- goto TWO_ARG;
- x = vs_base[0];
- switch (type_of(x)) {
-
- case t_fixnum:
- case t_bignum:
- vs_push(small_fixnum(0));
- return;
-
- case t_ratio:
- q = x;
- y = small_fixnum(1);
- goto RATIO;
-
- case t_shortfloat:
- d = (double)(sf(x));
- q1 = double_to_integer(d);
- d -= number_to_double(q1);
- if (sf(x) > 0.0 && d != 0.0) {
- vs_push(q1);
- q1 = one_plus(q1);
- d -= 1.0;
- }
- vs_base = vs_top;
- vs_push(q1);
- vs_push(make_shortfloat((shortfloat)d));
- return;
-
- case t_longfloat:
- d = lf(x);
- q1 = double_to_integer(d);
- d -= number_to_double(q1);
- if (lf(x) > 0.0 && d != 0.0) {
- vs_push(q1);
- q1 = one_plus(q1);
- d -= 1.0;
- }
- vs_base = vs_top;
- vs_push(q1);
- vs_push(make_longfloat(d));
- return;
-
- default:
- FEwrong_type_argument(TSor_rational_float, x);
- }
-
- TWO_ARG:
- if (n > 2)
- too_many_arguments();
- x = vs_base[0];
- y = vs_base[1];
- if ((type_of(x) == t_fixnum || type_of(x) == t_bignum) &&
- (type_of(y) == t_fixnum || type_of(y) == t_bignum)) {
- vs_base = vs_top;
- if (number_zerop(x)) {
- vs_push(small_fixnum(0));
- vs_push(small_fixnum(0));
- return;
- }
- vs_push(Cnil);
- vs_push(Cnil);
- integer_quotient_remainder_1(x, y, &vs_base[0], &vs_base[1]);
- if (number_plusp(x) ? number_plusp(y) : number_minusp(y)) {
- if (number_zerop(vs_base[1]))
- return;
- vs_base[0] = one_plus(vs_base[0]);
- vs_base[1] = number_minus(vs_base[1], y);
- }
- return;
- }
- check_type_or_rational_float(&vs_base[0]);
- check_type_or_rational_float(&vs_base[1]);
- q = number_divide(x, y);
- vs_push(q);
- switch (type_of(q)) {
- case t_fixnum:
- case t_bignum:
- vs_base = vs_top;
- vs_push(q);
- vs_push(small_fixnum(0));
- break;
-
- case t_ratio:
- RATIO:
- q1 = integer_divide1(q->rat.rat_num, q->rat.rat_den);
- if (number_plusp(q)) {
- vs_push(q1);
- q1 = one_plus(q1);
- } else
- q1 = q1;
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
-
- case t_shortfloat:
- case t_longfloat:
- q1 = double_to_integer(number_to_double(q));
- if (number_plusp(q1) && number_compare(q, q1)) {
- vs_push(q1);
- q1 = one_plus(q1);
- } else
- q1 = q1;
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
- }
- }
-
- Ltruncate()
- {
- object x, y, q, q1;
- int n;
-
- n = vs_top - vs_base;
- if (n == 0)
- too_few_arguments();
- if (n > 1)
- goto TWO_ARG;
- x = vs_base[0];
- switch (type_of(x)) {
-
- case t_fixnum:
- case t_bignum:
- vs_push(small_fixnum(0));
- return;
-
- case t_ratio:
- q1 = integer_divide1(x->rat.rat_num, x->rat.rat_den);
- vs_base = vs_top;
- vs_push(q1);
- vs_push(number_minus(x, q1));
- return;
-
- case t_shortfloat:
- q1 = double_to_integer((double)(sf(x)));
- vs_base = vs_top;
- vs_push(q1);
- vs_push(number_minus(x, q1));
- return;
-
- case t_longfloat:
- q1 = double_to_integer(lf(x));
- vs_base = vs_top;
- vs_push(q1);
- vs_push(number_minus(x, q1));
- return;
-
- default:
- FEwrong_type_argument(TSor_rational_float, x);
- }
-
- TWO_ARG:
- if (n > 2)
- too_many_arguments();
- x = vs_base[0];
- y = vs_base[1];
- if ((type_of(x) == t_fixnum || type_of(x) == t_bignum) &&
- (type_of(y) == t_fixnum || type_of(y) == t_bignum)) {
- integer_quotient_remainder_1(x, y, &vs_base[0], &vs_base[1]);
- return;
- }
- check_type_or_rational_float(&vs_base[0]);
- check_type_or_rational_float(&vs_base[1]);
- q = number_divide(x, y);
- vs_push(q);
- switch (type_of(q)) {
- case t_fixnum:
- case t_bignum:
- vs_base = vs_top;
- vs_push(q);
- vs_push(small_fixnum(0));
- break;
-
- case t_ratio:
- q1 = integer_divide1(q->rat.rat_num, q->rat.rat_den);
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
-
- case t_shortfloat:
- case t_longfloat:
- q1 = double_to_integer(number_to_double(q));
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
- }
- }
-
- Lround()
- {
- object x, y, q, q1, r;
- double d;
- int n, c;
- object one_plus(), one_minus();
-
- n = vs_top - vs_base;
- if (n == 0)
- too_few_arguments();
- if (n > 1)
- goto TWO_ARG;
- x = vs_base[0];
- switch (type_of(x)) {
-
- case t_fixnum:
- case t_bignum:
- vs_push(small_fixnum(0));
- return;
-
- case t_ratio:
- q = x;
- y = small_fixnum(1);
- goto RATIO;
-
- case t_shortfloat:
- d = (double)(sf(x));
- if (d >= 0.0)
- q = double_to_integer(d + 0.5);
- else
- q = double_to_integer(d - 0.5);
- d -= number_to_double(q);
- if (d == 0.5 && number_oddp(q)) {
- vs_push(q);
- q = one_plus(q);
- d = -0.5;
- }
- if (d == -0.5 && number_oddp(q)) {
- vs_push(q);
- q = one_minus(q);
- d = 0.5;
- }
- vs_base = vs_top;
- vs_push(q);
- vs_push(make_shortfloat((shortfloat)d));
- return;
-
- case t_longfloat:
- d = lf(x);
- if (d >= 0.0)
- q = double_to_integer(d + 0.5);
- else
- q = double_to_integer(d - 0.5);
- d -= number_to_double(q);
- if (d == 0.5 && number_oddp(q)) {
- vs_push(q);
- q = one_plus(q);
- d = -0.5;
- }
- if (d == -0.5 && number_oddp(q)) {
- vs_push(q);
- q = one_minus(q);
- d = 0.5;
- }
- vs_base = vs_top;
- vs_push(q);
- vs_push(make_longfloat(d));
- return;
-
- default:
- FEwrong_type_argument(TSor_rational_float, x);
- }
-
- TWO_ARG:
- if (n > 2)
- too_many_arguments();
- x = vs_base[0];
- y = vs_base[1];
- check_type_or_rational_float(&vs_base[0]);
- check_type_or_rational_float(&vs_base[1]);
- q = number_divide(x, y);
- vs_push(q);
- switch (type_of(q)) {
- case t_fixnum:
- case t_bignum:
- vs_base = vs_top;
- vs_push(q);
- vs_push(small_fixnum(0));
- break;
-
- case t_ratio:
- RATIO:
- q1 = integer_divide1(q->rat.rat_num, q->rat.rat_den);
- vs_push(q1);
- r = number_minus(q, q1);
- vs_push(r);
- if ((c = number_compare(r, plus_half)) > 0 ||
- (c == 0 && number_oddp(q1)))
- q1 = one_plus(q1);
- if ((c = number_compare(r, minus_half)) < 0 ||
- (c == 0 && number_oddp(q1)))
- q1 = one_minus(q1);
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
-
- case t_shortfloat:
- case t_longfloat:
- d = number_to_double(q);
- if (d >= 0.0)
- q1 = double_to_integer(d + 0.5);
- else
- q1 = double_to_integer(d - 0.5);
- d -= number_to_double(q1);
- if (d == 0.5 && number_oddp(q1)) {
- vs_push(q1);
- q1 = one_plus(q1);
- }
- if (d == -0.5 && number_oddp(q1)) {
- vs_push(q1);
- q1 = one_minus(q1);
- }
- vs_base = vs_top;
- vs_push(q1);
- vs_push(remainder(x, y, q1));
- return;
- }
- }
-
- Lmod()
- {
- check_arg(2);
- Lfloor();
- vs_base++;
- }
-
- Lrem()
- {
- check_arg(2);
- Ltruncate();
- vs_base++;
- }
-
-
- Ldecode_float()
- {
- object x;
- double d;
- int e, s;
-
- check_arg(1);
- check_type_float(&vs_base[0]);
- x = vs_base[0];
- if (type_of(x) == t_shortfloat)
- d = sf(x);
- else
- d = lf(x);
- if (d >= 0.0)
- s = 1;
- else {
- d = -d;
- s = -1;
- }
- e = double_exponent(d);
- d = set_exponent(d, 0);
- vs_top = vs_base;
- if (type_of(x) == t_shortfloat) {
- vs_push(make_shortfloat((shortfloat)d));
- vs_push(make_fixnum(e));
- vs_push(make_shortfloat((shortfloat)s));
- } else {
- vs_push(make_longfloat(d));
- vs_push(make_fixnum(e));
- vs_push(make_longfloat((double)s));
- }
- }
-
- Lscale_float()
- {
- object x;
- double d;
- int e, k;
-
- check_arg(2);
- check_type_float(&vs_base[0]);
- x = vs_base[0];
- if (type_of(vs_base[1]) == t_fixnum)
- k = fix(vs_base[1]);
- else
- FEerror("~S is an illegal exponent.", 1, vs_base[1]);
- if (type_of(x) == t_shortfloat)
- d = sf(x);
- else
- d = lf(x);
- e = double_exponent(d) + k;
- #ifdef VAX
- if (e <= -128 || e >= 128)
- #endif
- #ifdef IBMRT
-
- #endif
- #ifdef IEEEFLOAT
- if (type_of(x) == t_shortfloat && (e <= -126 || e >= 130) ||
- type_of(x) == t_longfloat && (e <= -1022 || e >= 1026))
- #endif
- #ifdef MV
-
- #endif
- #ifdef S3000
- if (e < -64 || e >= 64)
- #endif
- FEerror("~S is an illegal exponent.", 1, vs_base[1]);
- d = set_exponent(d, e);
- vs_pop;
- if (type_of(x) == t_shortfloat)
- vs_base[0] = make_shortfloat((shortfloat)d);
- else
- vs_base[0] = make_longfloat(d);
- }
-
- Lfloat_radix()
- {
- check_arg(1);
- check_type_float(&vs_base[0]);
- #ifdef VAX
- vs_base[0] = small_fixnum(2);
- #endif
- #ifdef IBMRT
-
- #endif
- #ifdef IEEEFLOAT
- vs_base[0] = small_fixnum(2);
- #endif
- #ifdef MV
-
- #endif
- #ifdef S3000
- vs_base[0] = small_fixnum(16);
- #endif
- }
-
- Lfloat_sign()
- {
- object x;
- int narg;
- double d, f;
-
- narg = vs_top - vs_base;
- if (narg < 1)
- too_few_arguments();
- else if (narg > 2)
- too_many_arguments();
- check_type_float(&vs_base[0]);
- x = vs_base[0];
- if (type_of(x) == t_shortfloat)
- d = sf(x);
- else
- d = lf(x);
- if (narg == 1)
- f = 1.0;
- else {
- check_type_float(&vs_base[1]);
- x = vs_base[1];
- if (type_of(x) == t_shortfloat)
- f = sf(x);
- else
- f = lf(x);
- if (f < 0.0)
- f = -f;
- }
- if (d < 0.0)
- f = -f;
- vs_top = vs_base;
- if (type_of(x) == t_shortfloat)
- vs_push(make_shortfloat((shortfloat)f));
- else
- vs_push(make_longfloat(f));
- }
-
- Lfloat_digits()
- {
- check_arg(1);
- check_type_float(&vs_base[0]);
- if (type_of(vs_base[0]) == t_shortfloat)
- vs_base[0] = small_fixnum(6);
- else
- vs_base[0] = small_fixnum(14);
- }
-
- Lfloat_precision()
- {
- object x;
-
- check_arg(1);
- check_type_float(&vs_base[0]);
- x = vs_base[0];
- if (type_of(x) == t_shortfloat)
- if (sf(x) == 0.0)
- vs_base[0] = small_fixnum(0);
- else
- vs_base[0] = small_fixnum(6);
- else
- if (lf(x) == 0.0)
- vs_base[0] = small_fixnum(0);
- else
- #ifdef VAX
- vs_base[0] = small_fixnum(14);
- #endif
- #ifdef IBMRT
-
- #endif
- #ifdef IEEEFLOAT
- vs_base[0] = small_fixnum(13);
- #endif
- #ifdef MV
-
- #endif
- #ifdef S3000
- vs_base[0] = small_fixnum(14);
- #endif
- }
-
- Linteger_decode_float()
- {
- object x;
- int h, l, e, s;
-
- check_arg(1);
- check_type_float(&vs_base[0]);
- x = vs_base[0];
- vs_base = vs_top;
- if (type_of(x) == t_longfloat) {
- integer_decode_double(lf(x), &h, &l, &e, &s);
- if (h != 0)
- vs_push(bignum2(h, l));
- else
- vs_push(make_fixnum(l));
- vs_push(make_fixnum(e));
- vs_push(make_fixnum(s));
- } else {
- integer_decode_float((double)(sf(x)), &h, &e, &s);
- vs_push(make_fixnum(h));
- vs_push(make_fixnum(e));
- vs_push(make_fixnum(s));
- }
- }
-
- Lcomplex()
- {
- object x, r, i;
- int narg;
-
- narg = vs_top - vs_base;
- if (narg < 1)
- too_few_arguments();
- if (narg > 2)
- too_many_arguments();
- check_type_or_rational_float(&vs_base[0]);
- r = vs_base[0];
- if (narg == 1)
- i = small_fixnum(0);
- else {
- check_type_or_rational_float(&vs_base[1]);
- i = vs_base[1];
- }
- vs_top = vs_base;
- vs_push(make_complex(r, i));
- }
-
- Lrealpart()
- {
- object r, x;
-
- check_arg(1);
- check_type_number(&vs_base[0]);
- x = vs_base[0];
- if (type_of(x) == t_complex)
- vs_base[0] = x->cmp.cmp_real;
- }
-
- Limagpart()
- {
- object x;
-
- check_arg(1);
- check_type_number(&vs_base[0]);
- x = vs_base[0];
- switch (type_of(x)) {
- case t_fixnum:
- case t_bignum:
- case t_ratio:
- vs_base[0] = small_fixnum(0);
- break;
- case t_shortfloat:
- vs_base[0] = shortfloat_zero;
- break;
- case t_longfloat:
- vs_base[0] = longfloat_zero;
- break;
- case t_complex:
- vs_base[0] = x->cmp.cmp_imag;
- break;
- }
- }
-
- init_num_co()
- {
- int l[2];
- float smallest_float, biggest_float;
- double smallest_double, biggest_double;
- float float_epsilon, float_negative_epsilon;
- double double_epsilon, double_negative_epsilon;
-
- #ifdef VAX
- l[0] = 0x80;
- l[1] = 0;
- smallest_float = *(float *)l;
- smallest_double = *(double *)l;
- #endif
-
- #ifdef IBMRT
-
-
-
-
- #endif
-
- #ifdef IEEEFLOAT
- #ifdef NS32K
-
-
-
-
-
- #else
- l[0] = 1;
- smallest_float = *(float *)l;
- l[0] = 0;
- l[1] = 1;
- smallest_double = *(double *)l;
- #endif
- #endif
-
- #ifdef MV
-
-
-
-
- #endif
-
- #ifdef S3000
- l[0] = 0x00100000;
- l[1] = 0;
- smallest_float = *(float *)l;
- smallest_double = *(double *)l;
- #endif
-
- #ifdef VAX
- l[0] = 0xffff7fff;
- l[1] = 0xffffffff;
- biggest_float = *(float *)l;
- biggest_double = *(double *)l;
- #endif
-
- #ifdef IBMRT
-
-
-
-
- #endif
-
- #ifdef IEEEFLOAT
- #ifdef NS32K
-
-
-
-
-
- #else
- l[0] = 0x7f7fffff;
- biggest_float = *(float *)l;
- l[0] = 0x7fefffff;
- l[1] = 0xffffffff;
- biggest_double = *(double *)l;
- #endif
- #endif
-
- #ifdef MV
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #endif
-
- #ifdef S3000
- l[0] = 0x7fffffff;
- l[1] = 0xffffffff;
- l[0] = 0x7fffffff;
- l[1] = 0xffffffff;
- biggest_float = *(float *)l;
- biggest_float = *(float *)l;
- biggest_float = *(float *)l;
- biggest_float = 0.0;
- biggest_float = biggest_float + 1.0;
- biggest_float = biggest_float + 2.0;
- biggest_float = *(float *)l;
- biggest_float = *(float *)l;
- strcmp("I don't like", "DATA GENERAL.");
- biggest_float = *(float *)l;
- biggest_double = *(double *)l;
- biggest_double = *(double *)l;
- biggest_double = *(double *)l;
- biggest_double = 0.0;
- biggest_double = biggest_double + 1.0;
- biggest_double = biggest_double + 2.0;
- biggest_double = *(double *)l;
- biggest_double = *(double *)l;
- strcmp("I don't like", "DATA GENERAL.");
- biggest_double = *(double *)l;
- #endif
-
- for (float_epsilon = 1.0;
- (float)(1.0 + float_epsilon) != (float)1.0;
- float_epsilon /= 2.0)
- ;
- for (float_negative_epsilon = 1.0;
- (float)(1.0 - float_negative_epsilon) != (float)1.0;
- float_negative_epsilon /= 2.0)
- ;
- for (double_epsilon = 1.0;
- 1.0 + double_epsilon != 1.0;
- double_epsilon /= 2.0)
- ;
- for (double_negative_epsilon = 1.0;
- 1.0 - double_negative_epsilon != 1.0;
- double_negative_epsilon /= 2.0)
- ;
-
- make_constant("MOST-POSITIVE-SHORT-FLOAT",
- make_shortfloat(biggest_float));
- make_constant("LEAST-POSITIVE-SHORT-FLOAT",
- make_shortfloat(smallest_float));
- make_constant("LEAST-NEGATIVE-SHORT-FLOAT",
- make_shortfloat(-smallest_float));
- make_constant("MOST-NEGATIVE-SHORT-FLOAT",
- make_shortfloat(-biggest_float));
-
- make_constant("MOST-POSITIVE-SINGLE-FLOAT",
- make_longfloat(biggest_double));
- make_constant("LEAST-POSITIVE-SINGLE-FLOAT",
- make_longfloat(smallest_double));
- make_constant("LEAST-NEGATIVE-SINGLE-FLOAT",
- make_longfloat(-smallest_double));
- make_constant("MOST-NEGATIVE-SINGLE-FLOAT",
- make_longfloat(-biggest_double));
-
- make_constant("MOST-POSITIVE-DOUBLE-FLOAT",
- make_longfloat(biggest_double));
- make_constant("LEAST-POSITIVE-DOUBLE-FLOAT",
- make_longfloat(smallest_double));
- make_constant("LEAST-NEGATIVE-DOUBLE-FLOAT",
- make_longfloat(-smallest_double));
- make_constant("MOST-NEGATIVE-DOUBLE-FLOAT",
- make_longfloat(-biggest_double));
-
- make_constant("MOST-POSITIVE-LONG-FLOAT",
- make_longfloat(biggest_double));
- make_constant("LEAST-POSITIVE-LONG-FLOAT",
- make_longfloat(smallest_double));
- make_constant("LEAST-NEGATIVE-LONG-FLOAT",
- make_longfloat(-smallest_double));
- make_constant("MOST-NEGATIVE-LONG-FLOAT",
- make_longfloat(-biggest_double));
-
- make_constant("SHORT-FLOAT-EPSILON",
- make_shortfloat(float_epsilon));
- make_constant("SINGLE-FLOAT-EPSILON",
- make_longfloat(double_epsilon));
- make_constant("DOUBLE-FLOAT-EPSILON",
- make_longfloat(double_epsilon));
- make_constant("LONG-FLOAT-EPSILON",
- make_longfloat(double_epsilon));
-
- make_constant("SHORT-FLOAT-NEGATIVE-EPSILON",
- make_shortfloat(float_negative_epsilon));
- make_constant("SINGLE-FLOAT-NEGATIVE-EPSILON",
- make_longfloat(double_negative_epsilon));
- make_constant("DOUBLE-FLOAT-NEGATIVE-EPSILON",
- make_longfloat(double_negative_epsilon));
- make_constant("LONG-FLOAT-NEGATIVE-EPSILON",
- make_longfloat(double_negative_epsilon));
-
- plus_half = make_ratio(small_fixnum(1), small_fixnum(2));
- enter_mark_origin(&plus_half);
-
- minus_half = make_ratio(small_fixnum(-1), small_fixnum(2));
- enter_mark_origin(&minus_half);
-
- make_function("FLOAT", Lfloat);
- make_function("NUMERATOR", Lnumerator);
- make_function("DENOMINATOR", Ldenominator);
- make_function("FLOOR", Lfloor);
- make_function("CEILING", Lceiling);
- make_function("TRUNCATE", Ltruncate);
- make_function("ROUND", Lround);
- make_function("MOD", Lmod);
- make_function("REM", Lrem);
- make_function("DECODE-FLOAT", Ldecode_float);
- make_function("SCALE-FLOAT", Lscale_float);
- make_function("FLOAT-RADIX", Lfloat_radix);
- make_function("FLOAT-SIGN", Lfloat_sign);
- make_function("FLOAT-DIGITS", Lfloat_digits);
- make_function("FLOAT-PRECISION", Lfloat_precision);
- make_function("INTEGER-DECODE-FLOAT", Linteger_decode_float);
- make_function("COMPLEX", Lcomplex);
- make_function("REALPART", Lrealpart);
- make_function("IMAGPART", Limagpart);
- }
-